/**
 * Input - L5
 *
 * @author dev@lonphy.com
 * @version 0.1
 */
(function(exports){
	"use strict";

	let inited = false,			// 输入设备是否实例化
		gKeyboard = null,		// 键盘设备
		gGamePad = null;		// 游戏设备


	// 键盘设备
	function L5Keyboard(){
		this._table = {};
		this.initEvent();
	}

	L5Keyboard.keydownHandler	= function(evt){ gKeyboard.down.call(gKeyboard, evt.keyCode); };
	L5Keyboard.keyupHandler		= function(evt){ gKeyboard.up.call(gKeyboard, evt.keyCode); };

	L5Keyboard.prototype = {
		constructor: L5Keyboard,
		down: function(keycode){
			this._table[keycode] = true;
		},
		up: function(keycode){
			this._table[keycode] = false;
		},
		initEvent: function() {
			window.addEventListener('keydown', L5Keyboard.keydownHandler, false);
			window.addEventListener('keyup', L5Keyboard.keyupHandler, false);
		},
		destory: function() {
			window.removeEventListener('keydown', L5Keyboard.keydownHandler, false);
			window.removeEventListener('keyup', L5Keyboard.keyupHandler, false);
		}
	};

	// 按键定义
	L5Keyboard.KEYS = Object.create(null);
	Object.defineProperties(L5Keyboard.KEYS, {
		LEFT:  {value:37, enumerable: true},
		UP:    {value:38, enumerable: true},
		RIGHT: {value:39, enumerable: true},
		DOWN:  {value:40, enumerable: true},
		RISE:  {value:33, enumerable: true},
		BOW:   {value:34, enumerable: true}
	});

/*******************************************************************************************/
	// 摇杆值
	function StickValue(x,y) {
		this.x = x;
		this.y = y;
	}

	// 游戏输入设备
	function L5GamePad() {
		// TODO: 自定义映射层
		this._table = {};
		this._leftStick = new StickValue(0,0);
		this._rightStick = new StickValue(0,0);

		this.initEvent();
	}

	// 按键定义
	L5GamePad.KEYS = Object.create(null);
	Object.defineProperties(L5GamePad.KEYS, {
		LEFT:  {value:5, enumerable: true},
		UP:    {value:6, enumerable: true},
		RIGHT: {value:7, enumerable: true},
		DOWN:  {value:8, enumerable: true}
	});

	L5GamePad.connected = false;	// 连接状态


	// 连接事件处理器
	L5GamePad.connectedHandler = function(e) {
		console.log("新游戏设备连接", e);
		L5GamePad.connected = true;
		gGamePad.pressHandler();
	};

	// 断开事件处理器
	L5GamePad.disConnectedHandler = function(e) {
		L5GamePad.connected = false;
		console.log("断开了", e);
	};

	// 按键事件处理器
	L5GamePad.prototype.pressHandler = function() {
		if (!L5GamePad.connected) return;
		let gp = navigator.getGamepads()[0];

		for(let i=0, l=gp.buttons.length;i<l;++i) {
			this._table[i] = gp.buttons[i].pressed;
		}

		this._leftStick.x = gp.axes[0];
		this._leftStick.y = gp.axes[1];
		this._rightStick.x = gp.axes[2];
		this._rightStick.y = gp.axes[3];

		requestAnimationFrame(function(){
			gGamePad.pressHandler.call(gGamePad);
		});
	};

	L5GamePad.prototype.initEvent = function() {
		window.addEventListener("gamepadconnected", L5GamePad.connectedHandler, false);
		window.addEventListener("gamepaddisconnected", L5GamePad.disConnectedHandler, false);
	};

	L5GamePad.prototype.destory = function() {
		window.removeEventListener('gamepadconnected', L5GamePad.connectedHandler, false);
		window.removeEventListener('gamepaddisconnected', L5GamePad.disConnectedHandler, false);
	};


	exports.Input = {
		/**
		 * 输入设备初始化
		 */
		init: function(){
			if (inited) return;	// 只能实例化一次
			gKeyboard = new L5Keyboard();
			gGamePad = new L5GamePad();
		},

		/**
		 * 移除输入设备
		 */
		destory: function(){
			if (!inited) return;
			gKeyboard && gKeyboard.destory();
			gGamePad && gGamePad.destory();
			gKeyboard = null;
			gGamePad = null;
		},

		/**
		 * 获取当前按键状态
		 */
		getMapState: function(){
			let ret = {
				'LEFT': false,
				'RIGHT': false,
				'UP': false,
				'DOWN': false,
				'RISE': false,
				'BOW' : false
			};

			// 键盘按键检查
			if(gKeyboard !== null) {
				if(gKeyboard._table[L5Keyboard.KEYS.LEFT]){
					ret.LEFT = true;
				}
				if(gKeyboard._table[L5Keyboard.KEYS.RIGHT]) {
					ret.RIGHT = true;
				}
				if(gKeyboard._table[L5Keyboard.KEYS.UP]){
					ret.UP = true;
				}
				if(gKeyboard._table[L5Keyboard.KEYS.DOWN]){
					ret.DOWN = true;
				}
				if(gKeyboard._table[L5Keyboard.KEYS.RISE]){
					ret.RISE = true;
				}
				if(gKeyboard._table[L5Keyboard.KEYS.BOW]){
					ret.BOW = true;
				}
			}

			// 游戏设备按键检查
			if (gGamePad !== null ) {
				if(gGamePad._leftStick.x == -1){
					ret.LEFT = true;
				}
				if(gGamePad._leftStick.x == 1) {
					ret.RIGHT = true;
				}
				if(gGamePad._leftStick.y == -1){
					ret.UP = true;
				}
				if(gGamePad._leftStick.y == 1){
					ret.DOWN = true;
				}
			}
			return ret;
		},

		/**
		 * 可使用的键盘映射集合
		 */
		KEYBORDER: L5Keyboard.KEYS,

		/**
		 * 可使用的游戏输入设备映射集合
		 */
		GAMEPAD: L5GamePad.KEYS
	};
})(window.L5);